/**
 * 找到 被选中元素的下标
 * @param {Array} originArr 目标数组
 * @param {Array} selVals 被选元素
 * @returns {Array} 被选中元素的下标
 */
function findOrderSelectValIndex(originArr, selVals) {
    var result = [];
    for (var i = 0, findIndex = 0; i < selVals.length; i++) {
        var selValElement = selVals[i];
        for (; findIndex < originArr.length; findIndex++) {
            if (selValElement == originArr[findIndex]) {
                result[i] = findIndex;
                break;
            }
        }
    }
    return result;
}

/**
 * 被选中的元素往下移动
 * @param {Array}  selectVal 被选中元素
 * @returns {Array} 返回移动后的结果
 */
function arrayMoveDown(originArr, selectVal) {
    // 查找被选中元素的 索引集合
    var selectValIndexArr = findOrderSelectValIndex(originArr, selectVal);
    if (selectValIndexArr.length == 0 || originArr.length == selectValIndexArr.length) {
        // 没有被选中的元素时，无须移动
        return originArr;
    }
    var newResult = [];
    var canMove = false;
    for (var originIndex = originArr.length - 1, selValIndex = selectValIndexArr.length - 1; originIndex >= 0; originIndex--) {
        if (originIndex == selectValIndexArr[selValIndex] && selValIndex >= 0) {
            if (canMove) {
                // 1. 初始化当前位置的元素
                newResult[originIndex] = originArr[originIndex];
                // 2. 与 下一个元素 交换位置(当前元素下移)
                var swap = newResult[originIndex + 1];
                newResult[originIndex + 1] = newResult[originIndex];
                newResult[originIndex] = swap;
                canMove = true;
            } else {
                newResult[originIndex] = originArr[originIndex];
            }
            // 待移动元素
            selValIndex--;
            continue;
        }

        canMove = true;
        newResult[originIndex] = originArr[originIndex];
    }
    return newResult;
}

/**
 * 被选中的元素往上移动
 * @param {Array} selectVal 被选中元素
 * @returns {Array}  返回移动后的结果
 */
function arrayMoveUp(originArr, selectVal) {
    // 查找被选中元素的 索引集合（一定是排好序的）
    var selectValIndexArr = findOrderSelectValIndex(originArr, selectVal);
    if (selectValIndexArr.length == 0 && selectValIndexArr.length == originArr.length) {
        // 没有被选中的元素或所有元素都被选中时，无须移动
        return originArr;
    }
    var newResult = [];
    var canMove = false;
    // selValIndex 是指向被选中元素的索引
    // originIndex 是指向原数组的索引
    for (var originIndex = 0, selValIndex = 0; originIndex < originArr.length; originIndex++) {
        if (originIndex == selectValIndexArr[selValIndex] && selValIndex < selectValIndexArr.length) {
            // 当 原数组的索引 是被选中 的
            if (canMove) {
                // 1. 初始化当前位置的元素
                newResult[originIndex] = originArr[originIndex];
                // 2. 与 前一个元素 交换位置(当前元素上移)
                var swap = newResult[originIndex - 1];
                newResult[originIndex - 1] = newResult[originIndex];
                newResult[originIndex] = swap;
                canMove = true;
            } else {
                newResult[originIndex] = originArr[originIndex];
            }
            // 被选中元素的索引 进行移动
            selValIndex++;
            continue;
        }
        // 当有没有被选中的元素时，才可以移动
        canMove = true;
        newResult[originIndex] = originArr[originIndex];
    }
    return newResult;
}

/**
 * 把选中元素移动到顶部
 * @param {Array}  selectVal 被选中元素
 * @returns {Array}  返回移动后的结果
 */
function arrayMoveTop(originArr, selectVal) {
    // 查找被选中元素的 索引集合
    var selectValIndexArr = findOrderSelectValIndex(originArr, selectVal);
    if (selectValIndexArr.length == 0) {
        // 没有被选中的元素时，无须移动
        return originArr;
    }
    var newResult = [];
    for (var originIndex = 0, selValIndex = 0, afterSelIndex = selectValIndexArr.length; originIndex < originArr.length; originIndex++) {
        if (originIndex == selectValIndexArr[selValIndex] && selValIndex < selectValIndexArr.length) {
            newResult[selValIndex] = originArr[originIndex];
            selValIndex++;
        } else {
            newResult[afterSelIndex] = originArr[originIndex];
            afterSelIndex++
        }
    }
    return newResult;
}

/**
 * 把选中元素移动到底部
 * @param {Array}  selectVal 被选中元素
 * @returns {Array}  返回移动后的结果
 */
function arrayMoveBottom(originArr, selectVal) {
    // 查找被选中元素的 索引集合
    var selectValIndexArr = findOrderSelectValIndex(originArr, selectVal);
    if (selectValIndexArr.length == 0) {
        // 没有被选中的元素时，无须移动
        return this.origin;
    }
    var newResult = [];

    for (var originIndex = 0, selValIndex = 0, beforeSelIndex = 0; originIndex < originArr.length; originIndex++) {
        if (originIndex == selectValIndexArr[selValIndex] && selValIndex < selectValIndexArr.length) {
            var tmpIndex = originArr.length - selectValIndexArr.length + selValIndex;
            newResult[tmpIndex] = originArr[originIndex];
            selValIndex++
        } else {
            newResult[beforeSelIndex] = originArr[originIndex];
            beforeSelIndex++;
        }
    }
    return newResult;
}

/**
 * 查找被选中元素的索引值
 * @param {Array} selectVal 被选中元素
 * @returns {Array}
 */
function findSelectValIndex(selectVal) {
    var result = [];
    for (var i = 0; i < selectVal.length; i++) {
        var selValElement = selectVal[i];
        result[i] = findIndexByEle(selValElement);
    }
    return result;
}

/**
 * 查找指定元素的索引
 * @param ele 被找元素
 * @returns {number} 被找元素的索引
 */
function findIndexByEle(ele, targetArr) {
    for (var i = 0; i < targetArr.length; i++) {
        if (targetArr == ele) {
            return i;
        }
    }
    return -1;
}


/**
 * 判断时间是否重叠，否的话时间会被添加到数组中
 * @param arr 数组
 * @param startTime 开始时间
 * @param endTime 结束时间
 * @returns {boolean}
 */
function timeOverlap(arr, startTime, endTime) {
    if (arr.length <= 0) {
        arr.push({startTime: startTime, endTime: endTime});
        return false;
    }
    for (var i = 0; i < arr.length; i++) {
        if (startTime >= arr[i].startTime && startTime <= arr[i].endTime) {
            return true;
        }
        if (endTime >= arr[i].startTime && endTime <= arr[i].endTime) {
            return true;
        }
        if (startTime <= arr[i].startTime && endTime >= arr[i].endTime) {
            return true;
        }
    }
    arr.push({startTime: startTime, endTime: endTime});
    return false;
}

